In Python, objects can declare their textual representation using the repr method. IPython expands on this idea and allows objects to declare other rich representations including:

  • HTML
  • JSON
  • PNG
  • JPEG
  • SVG
  • LaTeX

A single object can declare some or all of these representations; all are handled by IPython's display system.

In general the Notebook will use the richest available representation.

In [ ]:
from io import BytesIO
import urllib, base64

import matplotlib.pyplot as plt
from IPython.display import HTML

class KikoPlot:
    def __init__(self, x, y = None, caption = None):
        if y:
            self.x = x
            self.y = y
        else:
            self.y = x
            self.x = range(len(x))
        self.caption = caption
    
    def _to_png(self, fig):
        """Return a base64-encoded PNG from a 
        matplotlib figure.
        Stolen from:
        http://nbviewer.ipython.org/github/ipython-books/cookbook-code/blob/master/notebooks/chapter01_basic/06_kernel.ipynb"""
        imgdata = BytesIO()
        fig.savefig(imgdata, format='png')
        imgdata.seek(0)
        return urllib.parse.quote(
            base64.b64encode(imgdata.getvalue()))
    
    def _plot(self):
        fig = plt.figure(figsize=(4,4), dpi=100)
        plt.plot(self.x, self.y)
        self.result = self._to_png(fig)
        plt.close()
    
    def _repr_html_(self):
        self._plot()
        txt = """
<div style="width:600px;margin:auto;background-color:#0ff;">
  <img style="margin:auto;padding-top:25px;padding-bottom:10px;" src="data:image/png;base64,{0}"></img>
  <DIV STYLE="margin:auto;color:#0707ff;text-align:center;font-style:italic;">{1}</DIV>
</div>
        """
        return txt.format(self.result, self.caption)
In [ ]:
KikoPlot([1,2,3,4,3,2,1], caption = "Figure - 1. A very dumb plot.")

More